<?php

namespace App\Models;

use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder;
use App\Models\Traits\GoldRoundCacheTrait;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Factories\HasFactory;

/**
 * App\Models\GoldRound
 *
 * @property int $id
 * @property string|null $title
 * @property string|null $opened_at
 * @property string|null $started_at
 * @property string|null $ended_at
 * @property int $order
 * @property bool $is_close
 * @property bool $is_ending
 * @property-read bool $is_after_end_hour
 * @property-read bool $is_after_today_end
 * @property-read bool $is_after_today_open
 * @property-read bool $is_after_today_start
 * @property-read bool $is_before_today_end
 * @property-read bool $is_before_today_open
 * @property-read bool $is_before_today_start
 * @property-read bool $is_checking
 * @property-read bool $is_locking
 * @property-read bool $is_opening
 * @property-read bool $is_reclaiming
 * @property-read bool $is_running
 * @property-read bool $is_terminating
 * @property-read Carbon $today_ended_at
 * @property-read Carbon $today_opened_at
 * @property-read Carbon $today_started_at
 * @property-read Carbon $tomorrow_ended_at
 * @property-read Carbon $tomorrow_opened_at
 * @property-read Carbon $tomorrow_started_at
 * @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\GoldProduct[] $goldProducts
 * @property-read int|null $gold_products_count
 * @method static Builder|GoldRound available()
 * @method static \Database\Factories\GoldRoundFactory factory(...$parameters)
 * @method static Builder|GoldRound newModelQuery()
 * @method static Builder|GoldRound newQuery()
 * @method static Builder|GoldRound query()
 * @method static Builder|GoldRound whereEndedAt($value)
 * @method static Builder|GoldRound whereId($value)
 * @method static Builder|GoldRound whereIsClose($value)
 * @method static Builder|GoldRound whereIsEnding($value)
 * @method static Builder|GoldRound whereOpenedAt($value)
 * @method static Builder|GoldRound whereOrder($value)
 * @method static Builder|GoldRound whereStartedAt($value)
 * @method static Builder|GoldRound whereTitle($value)
 * @mixin \Eloquent
 * @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\GoldEnd[] $goldEnds
 * @property-read int|null $gold_ends_count
 * @method static Builder|GoldRound rewards()
 */
class GoldRound extends Model
{
    use HasFactory, GoldRoundCacheTrait;

    public $timestamps = false;

    protected $guarded = ['id'];

    protected $casts = [
	    'is_close' => 'boolean',
	    'is_ending' => 'boolean',
    ];

    public static function hasAnyPeak(): bool
    {
    	$rounds = self::available()->get();

    	if ($rounds->isEmpty()) return false;

    	$isPeak = false;
    	$time = Carbon::now();

    	foreach ($rounds as $round) {
		    $peakStoppedAt = $round->today_opened_at->addMinutes(15);
		    if ($time->gte($round->today_opened_at) and $time->lte($peakStoppedAt)) {
		    	$isPeak = true;
		    }
	    }

    	return $isPeak;
    }

    public static function hasAnyLock(): bool
    {
    	$rounds = self::available()->get();

    	if ($rounds->isEmpty()) return false;

    	$isLock = false;

    	foreach ($rounds as $round) {
		    if ($round->is_locking) {
		    	$isLock = true;
		    }
	    }

    	return $isLock;
    }

	public static function todayOpenedAt($rid)
	{
		$r = GoldRound::sGetCache($rid);
		$time = $r ? $r['today_opened_at'] : '3000-12-12 12:12:12';
		return Carbon::createFromFormat('Y-m-d H:i:s', $time);
	}

	public static function todayStartedAt($rid)
	{
		$r = GoldRound::sGetCache($rid);
		$time = $r ? $r['today_started_at'] : '3000-12-12 12:12:12';
		return Carbon::createFromFormat('Y-m-d H:i:s', $time);
	}

	public static function todayEndedAt($rid)
	{
		$r = GoldRound::sGetCache($rid);
		$time = $r ? $r['today_ended_at'] : '3000-12-12 12:12:12';
		return Carbon::createFromFormat('Y-m-d H:i:s', $time);
	}

	public function getTodayOpenedAtAttribute(): Carbon
	{
		$time = explode(':', $this->opened_at);
		return Carbon::today()->hour($time[0])->minute($time[1])->second($time[2]);
	}

	public function getTodayStartedAtAttribute(): Carbon
	{
		$time = explode(':', $this->started_at);
		return Carbon::today()->hour($time[0])->minute($time[1])->second($time[2]);
	}

	public function getTodayEndedAtAttribute(): Carbon
	{
		$time = explode(':', $this->ended_at);
		return Carbon::today()->hour($time[0])->minute($time[1])->second($time[2]);
	}

	public function getTomorrowOpenedAtAttribute(): Carbon
	{
		$time = explode(':', $this->opened_at);
		return Carbon::tomorrow()->hour($time[0])->minute($time[1])->second($time[2]);
	}

	public function getTomorrowStartedAtAttribute(): Carbon
	{
		$time = explode(':', $this->started_at);
		return Carbon::tomorrow()->hour($time[0])->minute($time[1])->second($time[2]);
	}

	public function getTomorrowEndedAtAttribute(): Carbon
	{
		$time = explode(':', $this->ended_at);
		return Carbon::tomorrow()->hour($time[0])->minute($time[1])->second($time[2]);
	}

	public function getIsBeforeTodayOpenAttribute(): bool
	{
		return Carbon::now()->lt($this->today_opened_at);
	}

	public function getIsAfterTodayOpenAttribute(): bool
	{
		return Carbon::now()->gt($this->today_opened_at);
	}

	public function getIsBeforeTodayStartAttribute(): bool
	{
		return Carbon::now()->lt($this->today_started_at);
	}

	public function getIsAfterTodayStartAttribute(): bool
	{
		return Carbon::now()->gt($this->today_started_at);
	}

	public function getIsBeforeTodayEndAttribute(): bool
	{
		return Carbon::now()->lt($this->today_ended_at);
	}

	public function getIsAfterTodayEndAttribute(): bool
	{
		return Carbon::now()->gt($this->today_ended_at);
	}

	public function getIsOpeningAttribute(): bool
	{
		return $this->is_after_today_open and $this->is_before_today_start;
	}

	public function getIsReclaimingAttribute(): bool
	{
		$backMinutes = cs('storm')->take_back_gold_product_within_minutes;

		$time = Carbon::now();
		$startedAt = $this->today_started_at->addMinutes($backMinutes);
        $endedAt = $this->today_started_at->addMinutes($backMinutes+100);
		return $time->gt($startedAt) and $time->lte($endedAt);
	}

	public function getIsCheckingAttribute(): bool
	{
		$time = Carbon::now()->second(0)->toDateTimeString();

		$beforeCheckedAt = $this->today_opened_at->addMinutes(-5)->second(0)->toDateTimeString();
		$afterCheckedAt = $this->today_ended_at->addMinutes(5)->second(0)->toDateTimeString();

		return $time == $beforeCheckedAt or $time == $afterCheckedAt;
	}

	public function getIsTerminatingAttribute(): bool
	{
		$terminateMinutes = cs('storm')->terminate_gold_product_within_minutes;

		$time = Carbon::now();
		$startedAt = $this->today_started_at->addMinutes($terminateMinutes);
		return $time->gt($startedAt) and $time->lte($this->today_ended_at);
	}

	public function getIsRunningAttribute(): bool
	{
		return $this->is_after_today_start and $this->is_before_today_end;
	}

	public function getIsLockingAttribute(): bool
	{
		return $this->is_after_today_open and $this->is_before_today_end;
	}

	public function getIsAfterEndHourAttribute(): bool
	{
		return $this->is_after_today_open and $this->is_before_today_end;
	}

	public function scopeAvailable(Builder $builder): Builder
	{
		return $builder->where('is_close', false);
	}

	public function scopeRewards(Builder $builder): Builder
	{
		return $builder->where('is_close', false)->where('is_ending', false);
	}

	public function goldProducts(): HasMany
	{
		return $this->hasMany(GoldProduct::class);
	}

    public function goldEnds(): HasMany
    {
        return $this->hasMany(GoldEnd::class);
    }

	public function valueCount()
	{
		$record = GoldRecord::query()
			->where('gold_round_id', $this->id)
			->orderByDesc('id')->first();

		if (!$record) return 0;

		$ids = $this->goldProducts()
			->whereNull('disabled_at')
			->pluck('id');

		return GoldRecord::query()
			->whereDate('created_at', $record->created_at)
			->whereIn('gold_product_id', $ids)
			->sum('resell_all_price');
	}
}
